# !/usr/bin python3                                
# encoding: utf-8 -*-
# @file: tools.py                       
# @author   : wjd
# @Time: 2024/2/22 14:48

"""
@Desc: Antalpha Prime V2.8.0 封装http请求（对接BM钱包需求）
@Author: zhangpeiheng
@Date: 2024/02/1
"""

import base64
import json
import random
import requests
import string
import time
import urllib
import urllib3
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5


class OpenApiHttpRequest(object):

    def __init__(self, host, api_key, private_key):
        """
        :param host:
        :param api_key:
        :param private_key:
        """
        self.host = host
        self.private_key = private_key
        self.headers = {
            "content-type": "application/json",
            "Accept-Language": "zh-CN",
            "API-Key": api_key,
        }
        urllib3.disable_warnings()

    def get_signature(self, method, api_path, nonce, timestamp, body):
        """
        Desc：使用 RSA私钥 SHA1WithRSA生成签名# SHA256
        :param method: "GET" "POST"
        :param api_path: 接口地址，比如"/api/cloud/user/add"
        :param nonce: 8位随机字符串
        :param timestamp: 当前时间的13位时间戳
        :param body: 请求体
        :return: "oKRvW/CiyfWbFn7q+L246NKu0sjUK1o9vt6ZfzzahJUPH2SE69VV9e2iLl9mlNDaUHSPef5GTGzwOoqzGRvKMw=="
        """
        # 初始化签名对象（需要使用私钥）
        signer = PKCS1_v1_5.new(RSA.importKey(self.private_key))
        # 签名前准备的数据，HTTP_METHOD + | + HTTP_REQUEST_PATH +  | + NONCE + | + TIMESTAMP + | + BODY
        digest = SHA256.new("|".join([method, api_path, nonce, timestamp, body]).encode())
        # 使用私钥对数据生成 RSA 签名
        signature = base64.b64encode(signer.sign(digest))
        return signature.decode()

    def add_headers_info(self, method, path, params):
        """
        Desc：添加签名信息到请求头
        :param method: "GET" "POST"
        :param path: 接口地址，比如"/api/cloud/user/add"
        :param params: type:dict，比如{"accountReference": "123456781"}
        :return:
        """
        nonce = "".join(random.choices(string.ascii_letters + string.digits, k=8))
        timestamp = str(int(time.time() * 1000))
        body = ""
        if method == "POST":
            body = json.dumps(params)
        signature = self.get_signature(method, path, nonce, timestamp, body)
        self.headers.update(
            {
                "API-Signature": signature,
                "API-TIMESTAMP": timestamp,
                "API-NONCE": nonce,
            }
        )

    def api_get_with_signature(self, path, params):
        """
        Desc：加签名的get请求
        :param path: 接口地址，比如"/api/cloud/user/add"
        :param params: type:dict，比如{"accountReference": "123456781"}
        :return:
        """
        self.add_headers_info("GET", path, params)
        url = "{}{}?{}".format(self.host, path, urllib.parse.urlencode(params))
        response = requests.get(url=url, headers=self.headers, verify=False)
        format_str = "{}\nRequest URL: {}\nRequest Headers: {}\nResponse:\n{}"
        print(format_str.format("*" * 100, url, json.dumps(self.headers), response.text))
        return response.json()

    def api_post_with_signature(self, path, params):
        """
        Desc：加签名的post请求
        :param path: 接口地址，比如"/api/cloud/user/add"
        :param params: type:dict，比如{"accountReference": "123456781"}
        :return:
        """
        self.add_headers_info("POST", path, params)
        url = "{}{}".format(self.host, path)
        response = requests.post(url=url, json=params, headers=self.headers, verify=False)
        format_str = "{}\nRequest URL: {}\nRequest Headers: {}\nRequest Params: {}\nResponse: {}\nTrace-ID: {}"
        print(format_str.format("*" * 100, url, json.dumps(self.headers), json.dumps(params), response.text, response.headers.get("Trace-Id")))
        return response.json()


if __name__ == "__main__":
    host = "https://antalphatest2.metalpha.fund"
    # host = "http://antalphadev1.metalpha.fund"
    api_key = "testBM"
    # api_key = "wangC"
    private_key = """-----BEGIN PRIVATE KEY-----
        MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDPwVdDUPTosfbM
        aVLAIcwbdKzy4k5woqRJX0sd6vii1zhV6YBPY3awKlRecrneStwOlbNoGkfwosIp
        8r+4t00a7S+AxECHgjvwh7+Z/TlrFVjVImO3mI8rAkChp77+AplYJtpr5TB13evd
        Wh3HJuBzBw7U26iO8WPiEwa9z8cgMql/vtVYzFwje+2My5Abusau4TP7GFW2KcRH
        dyMr1UheFH6bniDBQAhAN+obI6i0My0m0cEt6kRKMm9fXT5Sts3igyK9BGNkaRNx
        hb+s4/WkN2vXrNhylkLSfYHAxxwN81deY3q/tk1bc2ZcPz8n8X7nmNXCjmfQ+RFC
        IM3GBHgvAgMBAAECggEAFxx4cyYd4IbvoAS1bmc0F/fOR4SyWihVo03lAtKBT0gm
        3bPIkMxNR0KmOQ2FLLviKAMyPonx58yLUfRNrKRDgRPSnX33ebucpGDNiTlYuldZ
        Fvio5CMmBhBNlU4eWo56dYp48NjBn9MMqoacWmuyO0mVNkurQB+NT3hzXwkuqx+U
        MWz//E5kjykh4wDsd45X0tJ6MRE7vTCF7fmRe+a64S93Pmdmo2DEk4FagkB/XCyl
        zqqo0EEuAiwstn58caFhQcs/xNVjZJfeahoauV2AONEXXEd5okpalSw2uttpa1WU
        6I5WYnG2voCLT8hzFmSPpD7lkF4RxoqYk7gEB3+tjQKBgQD5QQx7M/p39BIUwF6R
        53G4lmFj+rkuPVzYH1Gl5cCXG2KoYyQGzEDHnd0GvYm9IfY4yLJIEbmTR7NnVNwR
        bkZbWZ1tTH3qOBMDH6rQx5pHhSj7NsFn6mTnsy6qFwt+4sgBDGrag+xqhVNPNPzw
        NYAQDdQ2rz706pHDXpjmFmTurQKBgQDVYMSq01L50EzJyE52VKHYc/YPHh21SIJe
        8fcfXKbYanMJnWPa5lKY/U2hzcF471fVyiukDstcNtPWEU9MPsbVDx7+zsin1zFR
        BMdl843H9Ea9RRWUZE54VhxehD5VmOauMEm95SiQm+VZ1110ycISUGHnjzTBzDZ9
        yoI+MHepywKBgGhKBEvkYq8f6xTNrIQFv7pJCXTIqgSj3h37dLEiIWPYLH5iBOfn
        PE+JSLqSQXhmJlx59MZczDXIcVMR2YZdioicRVc/Awwl7CaJcHIsoeu81nnN3jx5
        gUDE4wh93ex4PNDbfjXxrtCe+k2Q0Sg8alnNP3al+oSFRPnmsbjLs+19AoGAfAp/
        CZdDuzmeCgdJpXxZgY0X0338YzA9qZgbwr2HuHNZYJOAQvZ1ub427QLBn93zP7MB
        X6PCEF9HEkCJypcL2zupFxN6jieI4cJXcCr/lueoX8rTWqpc+5ODdmaGHhh+sXAc
        zilzRW17DJkoGQZYrXDRGV2km6xtWP7qa+CdD7UCgYBl0+h1nVKTBiWVnL4REhFA
        a2YX3v0trGw6A5IXtQ/QI+Axttu7AwvsbB0rSD7guQGIM8Dgz1Guex+B/SUqwJQK
        R7Wq/u95RbPNmFVzXBvQ1WiOpR5wRCgq7dpr63fzH9/67aQeG6urf0KmTUv6lHIU
        VGDAGHgAiw/5n/lGjrR77g==
    -----END PRIVATE KEY-----"""

    api = OpenApiHttpRequest(host, api_key, private_key)
    #验证传入参数名和值合法时，接口请求成功
    paras = {
                "chainCode": "SETH"
                }
    #验证参数为空时，接口返回错误提示
    paras1 = {
                "chainCode": ""
                }
    #验证参数类型非法时，接口返回错误提示
    paras2 = {
                "chainCode": 123
                }
    #验证参数长度超过边界时，接口返回错误提示
    paras3 = {
                "chainCode": "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                             "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                             "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                             "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                             "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                }
    #验证传入的链不存在或不支持时，接口返回错误提示
    paras4 = {
                "chainCode": "USDT"
                }


    #验证参数为空时，接口返回错误提示
    paras_1 = {
                "address": ""
                }
    #验证参数类型非法时，接口返回错误提示
    paras_11 = {
                "address": 123
                }
    #验证参数长度超过500字符时，接口返回错误提示
    paras_12 = {
                "address":  "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                            "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                            "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                            "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                            "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
                }
    #验证查询的地址不存在时，接口返回错误提示
    paras_13 = {
                "address": "0x51f833b089df4becd4933d91de32911b68e10xxx"
                }
    #验证查询的是外部地址，接口返回错误提示
    paras_14 = {
                "address": "0x72F656ec3CA9911eFBf9C37E20ed809765d57711"
                }
    #验证查询的是不属于BM的cobo账户地址，接口返回错误提示
    paras_15 = {
                "address": "0x51f833b089df4becd4933d91de32911b68e10xxx"
                }
    #验证传入参数名和值合法时，接口请求成功
    paras_16 = {
                "address": "0xc6e23a10251f9339c789081369212d95e83a5886"
                }
    #获取cobo bm账户下已开通的所有币种
    api.api_post_with_signature("/api/prime/bitmain/v1/supportedCoins",paras)
    #创建地址接口     73`
    api.api_post_with_signature("/api/prime/bitmain/v1/generateAddresses", paras)
    #获取地址余额
    res = api.api_post_with_signature("/api/prime/bitmain/v1/getBalance", paras_16)
    print('\n')
    # print(res['result'])